home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc,comp.lang.perl
- From: Lutz Prechelt <prechelt@i41s14.ira.uka.de>
- Subject: v20i092: cgrep2 - context grep in perl, version 2, Part01/01
- Message-ID: <1991Jul10.020543.17296@sparky.IMD.Sterling.COM>
- X-Md4-Signature: fe1e3f8fb41eb9bf8df21657e63d1554
- Date: Wed, 10 Jul 1991 02:05:43 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Lutz Prechelt <prechelt@i41s14.ira.uka.de>
- Posting-number: Volume 20, Issue 92
- Archive-name: cgrep2/part01
- Supersedes: cgrep: Volume 20, Issue 88
-
- A few days ago I posted 'cgrep', Version 1.
- I got some feedback since then and worked over it;
- here is an upgrade. I think this will do for a while.
-
- HERE WE GO:
-
- The following is version 2 of cgrep (a Perl script).
- cgrep is a grep that gives you a number of context lines along with the
- matching line.
-
- The following changes occured in respect to version 1:
-
- I added options
- -i (ignore case)
- -c (count matches also)
-
- documented option
- -e (end the list of options)
-
- removed a bug in option
- -n which gave wrong line numbers in precontext
-
- and polished all a bit.
-
- For exact usage, see the message in the body of the script.
- You will probably have to edit the first line of the script,
- to tell it where your 'perl' resides.
-
- Lutz
-
- Lutz Prechelt (++49/721/608-4317, FAX: ++49/721/697760)
- Institut fuer Programmstrukturen und Datenorganisation
- Universitaet Karlsruhe; D-7500 Karlsruhe 1; Germany
- prechelt@ira.uka.de or prechelt!ira.uka.de@relay.csnet
- ----------------------------- cut here -----------------------------------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: cgrep
- # Wrapped by prechelt@Djibouti on Mon Jul 8 12:49:40 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'cgrep' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'cgrep'\"
- else
- echo shar: Extracting \"'cgrep'\" \(5904 characters\)
- sed "s/^X//" >'cgrep' <<'END_OF_FILE'
- X#!/tools/bin/perl
- X#
- X# Copyright (C) 1991 by Lutz Prechelt, Karlsruhe
- X#
- X# This program is free software; you can redistribute it and/or modify
- X# it under the terms of the GNU General Public License as published by
- X# the Free Software Foundation; either version 1, or (at your option)
- X# any later version.
- X# This program is distributed in the hope that it will be useful,
- X# but WITHOUT ANY WARRANTY; without even the implied warranty of
- X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X# GNU General Public License for more details.
- X# If you don't have a copy of the GNU General Public License write to
- X# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- X# Version: 2, Patchlevel 0
- X# Author: Lutz Prechelt (prechelt@ira.uka.de), 23.03.91
- X# Correction by Sridhar Vasudevan, 03.07.91
- X# Last Change: Lutz Prechelt, 04.07.91
- X#
- X# Usage: see message at "die" below.
- X
- X#---------- constants:
- X$infinity = 10000;
- X
- X#---------- Variables:
- X$delimiterstring = "-----------\n";
- X$matches = 0;
- X$precontext = 2;
- X$postcontext = 2;
- X$wrong_option = 0;
- X
- X#---------- boolean Options:
- X$paragraphmode = 0;
- X$count_matches = 0;
- X$ignorecase = 0;
- X$withlinenumber = 0;
- X$withfilename = 0;
- X$reversemode = 0;
- X
- X# $endpara = '\S.*\n';
- X
- X#---------- Subroutines:
- X
- Xsub match_found {
- X #bad style: uses the global variables $ignorecase, $reversemode, $cur, $pat
- X if ($ignorecase != 0) {
- X ($reversemode == 1 ? $cur !~ /$pat/io : $cur =~ /$pat/io);
- X }
- X else {
- X ($reversemode == 1 ? $cur !~ /$pat/o : $cur =~ /$pat/o);
- X }
- X}
- X
- Xsub showline {
- X if ($withfilename != 0) {
- X printf ("\"%s\"", $ARGV);
- X }
- X if ($withfilename != 0 && $withlinenumber != 0) {
- X print ",";
- X }
- X if ($withlinenumber != 0) {
- X printf ("%4d", $_[1]);
- X }
- X if ($withfilename != 0 || $withlinenumber != 0) {
- X print ": ";
- X }
- X print ($_[0]);
- X}
- X
- X
- X#---------- Process the Options:
- Xdo {
- X $something_done = 1;
- X if ($ARGV[0] =~ /^-(\d+)$/) {
- X $precontext = $postcontext = $1;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-(\d+)[\,\+\/\;](\d+)$/) {
- X $precontext = $1;
- X $postcontext = $2;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-d$/ && $#ARGV > 0) {
- X $delimiterstring = $ARGV[1];
- X $delimiterstring =~ s/\\n/\n/o;
- X shift; shift;
- X }
- X elsif ($ARGV[0] =~ /^-d(.*)$/) {
- X $delimiterstring = $1;
- X $delimiterstring =~ s/\\n/\n/o;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-c$/) {
- X $count_matches = 1;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-h$/) {
- X $withfilename = 1;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-i$/) {
- X $ignorecase = 1;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-n$/) {
- X $withlinenumber = 1;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-p$/) {
- X $paragraphmode = 1;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-v$/) {
- X $reversemode = 1;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-e$/) { # end options (for expressions starting
- with - )
- X $something_done = 0;
- X shift;
- X }
- X elsif ($ARGV[0] =~ /^-/) {
- X printf ("don't know option '%s'\n", $ARGV[0]);
- X $wrong_option = 1;
- X $something_done = 0;
- X shift;
- X }
- X else {
- X $something_done = 0;
- X }
- X} while ($something_done);
- X
- X
- X#---------- Usage message:
- Xif ($#ARGV == -1 || $wrong_option) {
- X die "
- X Usage: cgrep [-pre[,post]] [-p] [-v] [-c] [-h] [-n] [-d string]
- X [-e] pattern [file...]
- X
- X cgrep is a context grep. It displays more than the one matching line for
- X every match (2 before and 2 after as default).
- X
- X -3 means display 3 lines before and 3 lines after the match (e.g.)
- X -5,12 means display 5 lines before the match and 12 lines after (e.g.)
- X -p means display only as much of the context as belongs to the
- X current paragraph. (paragraphs bounded by empty lines)
- X -v means invert search (display nomatches)
- X -c means display number of matching lines at the end of run
- X -h means toggle display filename before every line
- X -i means ignore case when matching the regexp
- X -n means display line number before every line
- X -d string means use string as the output delimiter string
- X -e means end options (i.e. now comes the pattern,
- X for patterns starting with - )
- X pattern is a Perl regular expression (you better quote it !)
- XExiting";
- X}
- X
- X
- Xif (length (@ARGV) > 1) {
- X $withfilename = !$withfilename;
- X}
- X
- X
- X#---------- Get the pattern and protect the delimiter.
- X$pat = shift;
- X$pat =~ s#/#\\/#g;
- X
- X
- X#---------- current line will always be at end of array, i.e.
- $ary[$currentpre]
- X$_ = <>;
- Xpush(@ary,$_);
- X$currentpre = 0;
- X
- X#---------- do the search
- X# use @ary as a silo, shifting and pushing.
- X# the length of the @ary at any time is $currentpre + 1
- X# the current line is @ary[$currentpre], the postcontext is not held in @ary.
- X$seq = 0;
- X$lastoutput = $infinity; #last output is infinitely many lines ago
- X$cur = @ary[0]; #current line
- Xwhile ($cur) { #as long as there is something to look at
- X if (&match_found()) {
- X $matches++;
- X if ($lastoutput <= $postcontext) {
- X &showline ($cur, $.);
- X }
- X else {
- X print $delimiterstring if ($seq++ && $precontext + $postcontext > 0);
- X $lineno = $. - $#ary;
- X foreach $line (@ary) {
- X &showline ($line, $lineno++);
- X }
- X }
- X $lastoutput = 0;
- X }
- X elsif (($cur !~ /\S.*\n/o && $paragraphmode == 1) || eof) {
- #paragraph/file end
- X for (; $currentpre >= 0; $currentpre--) {
- X shift (@ary);
- X }
- X $lastoutput = $infinity;
- X close (ARGV) if (eof);
- X }
- X elsif ($lastoutput <= $postcontext) { #another line of postcontext
- X &showline ($cur, $.);
- X }
- X #goto next line of input:
- X $lastoutput++;
- X $_ = <> if $_;
- X push(@ary,$_);
- X if ($currentpre < $precontext) {
- X $currentpre++;
- X }
- X else {
- X shift(@ary);
- X }
- X $cur = $ary[$currentpre];
- X}
- X
- X
- X#---------- perhaps display number of matches:
- Xif ($count_matches != 0) {
- X printf ("%d\n", $matches);
- X}
- X
- X
- END_OF_FILE
- if test 5904 -ne `wc -c <'cgrep'`; then
- echo shar: \"'cgrep'\" unpacked with wrong size!
- fi
- chmod +x 'cgrep'
- # end of 'cgrep'
- fi
- echo shar: End of shell archive.
- exit 0
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-